package org.windchill955.query;

import ext.app.process.constant.CommonConstant;
import org.apache.commons.lang.StringUtils;
import wt.fc.*;
import wt.iba.definition.*;
import wt.iba.value.*;
import wt.pds.StatementSpec;
import wt.query.*;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.Iterated;
import wt.vc.config.LatestConfigSpec;

import java.sql.Timestamp;
import java.util.*;

/**
 * 查询帮助类，封装了高级查询-简化查询操作
 * <p>
 * 注意：这里使用的属性名称就是数据库列名称，不是ClassAttribute
 *
 * @author pengyk
 * @version 0.1
 */
public class QsHelper {
    //查询对象
    private final QuerySpec qs;
    //类.属性名 - 列对象
    private final Map<String, TableColumn> columnMap;
    //类别名 - 类位置
    private final Map<Class<?>, Integer> aliasIndexMap;
    //主类，即通过构造函数传入的类
    private final Class<? extends Persistable> mainClazz;

    /**
     * 获取内部查询对象
     * <p>
     * 当QsHelper封装的操作不能满足的时候可以使用此方法获取原始的查询对象进行任意操作
     *
     * @return 查询对象
     */
    public QuerySpec getQs() {
        return qs;
    }

    /**
     * 构建查询帮助类
     *
     * @param clazz 查询主类型
     */
    public QsHelper(Class<? extends Persistable> clazz) {
        this(clazz, true);
    }

    /**
     * 构建查询帮助类
     *
     * @param clazz       查询主类型
     * @param isFetchData 是否获取主类型的字段结果
     */
    public QsHelper(Class<? extends Persistable> clazz, boolean isFetchData) {
        mainClazz = clazz;
        columnMap = new HashMap<>();
        aliasIndexMap = new HashMap<>();
        try {
            qs = new QuerySpec();
            qs.setAdvancedQueryEnabled(true);
            appendClassList(clazz, isFetchData);
        } catch (QueryException e) {
            throw new WTQueryException(e);
        }
    }

    /**
     * 是否会继承查询
     * 即如果Class传入Workable，就会查询Workable下所有子类的表
     * <p>
     * 一定要非常金属调用此方法
     *
     * @param b true-允许，false-不允许
     */
    public void setDescendantQuery(boolean b) {
        try {
            qs.setDescendantQuery(b);
        } catch (WTPropertyVetoException e) {
            throw new WTQueryException(e);
        }
    }

    /**
     * 追加查询类型
     *
     * @param clazz       查询类型
     * @param isFetchData 是否获取对应数据
     * @return 查询类索引
     */
    public int appendClassList(Class<? extends Persistable> clazz, boolean isFetchData) {
        try {
            int index;
            if (aliasIndexMap.containsKey(clazz)) {
                index = aliasIndexMap.get(clazz);
            } else {
                index = qs.appendClassList(clazz, isFetchData);
                aliasIndexMap.put(clazz, index);
            }
            return index;
        } catch (QueryException e) {
            throw new WTQueryException(e);
        }
    }

    /**
     * 获取查询列对象
     *
     * @param clazz 查询类型
     * @param name  列名称
     * @return 查询列对象
     */
    private TableColumn createColumn(Class<? extends Persistable> clazz, String name) {
        Objects.requireNonNull(clazz);
        appendClassList(clazz, false);
        String key = clazz.getName() + "." + name;
        TableColumn column = columnMap.get(key);
        if (column == null) {
            int aliasIndex = aliasIndexMap.get(clazz);
            String alias = qs.getFromClause().getAliasAt(aliasIndex);
            column = new TableColumn(alias, name);
            columnMap.put(key, column);
        }
        return column;
    }

    /**
     * 追加and操作符
     *
     * @return 返回当前查询帮助类
     */
    public QsHelper and() {
        qs.appendAnd();
        return this;
    }

    /**
     * 追加or操作符
     *
     * @return 返回当前查询帮助类
     */
    public QsHelper or() {
        qs.appendOr();
        return this;
    }

    /**
     * 追加左括号，用于处理条件优先级
     *
     * @return 返回当前查询帮助类
     */
    public QsHelper openParen() {
        qs.appendOpenParen();
        return this;
    }

    /**
     * 添加and和左括号，即 AND (
     *
     * @return 返回当前查询帮助类
     */
    public QsHelper andOpenParen() {
        qs.appendAnd();
        qs.appendOpenParen();
        return this;
    }

    /**
     * 添加or和左括号，即 OR (
     *
     * @return 返回当前查询帮助类
     */
    public QsHelper orOpenParen() {
        qs.appendAnd();
        qs.appendOpenParen();
        return this;
    }

    /**
     * 追加右括号，用于处理条件优先级
     *
     * @return 返回当前查询帮助类
     */
    public QsHelper closeParen() {
        qs.appendCloseParen();
        return this;
    }

    /**
     * 追加条件
     *
     * @param exprA 左侧表达式
     * @param op    比较操作符
     * @param exprB 右侧表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper where(RelationalExpression exprA, String op, RelationalExpression exprB) {
        try {
            SearchCondition condition = new SearchCondition(exprA, op, exprB);
            qs.appendWhere(condition, new int[]{0});
        } catch (QueryException e) {
            throw new WTQueryException(e);
        }
        return this;
    }

    /**
     * 增加条件
     *
     * @param clazz     条件字段所在类型
     * @param name      条件字段名称
     * @param condition 条件 SearchCondition里面定义的条件
     * @param value     条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper where(Class<? extends Persistable> clazz, String name, String condition, Object value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, condition, new ConstantExpression(value));
    }

    /**
     * 增加任意条件
     *
     * @param name      条件字段名称
     * @param condition 条件 SearchCondition里面定义的条件
     * @param value     条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper where(String name, String condition, Object value) {
        return where(mainClazz, name, condition, value);
    }

    /**
     * 增加与等于条件
     *
     * @param exprA 左侧表达式
     * @param op    比较操作符
     * @param exprB 右侧表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper andWhere(RelationalExpression exprA, String op, RelationalExpression exprB) {
        qs.appendAnd();
        return where(exprA, op, exprB);
    }

    /**
     * 增加任意条件
     *
     * @param clazz     条件字段所在类型
     * @param name      条件字段名称
     * @param condition 条件 SearchCondition里面定义的条件
     * @param value     条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper andWhere(Class<? extends Persistable> clazz, String name, String condition, Object value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, condition, new ConstantExpression(value));
    }

    /**
     * 增加任意条件
     *
     * @param name      条件字段名称
     * @param condition 条件 SearchCondition里面定义的条件
     * @param value     条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper andWhere(String name, String condition, Object value) {
        return andWhere(mainClazz, name, condition, value);
    }

    /**
     * 或连接条件
     *
     * @param exprA 左侧表达式
     * @param op    比较操作符
     * @param exprB 右侧表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper orWhere(RelationalExpression exprA, String op, RelationalExpression exprB) {
        qs.appendOr();
        return where(exprA, op, exprB);
    }

    /**
     * 或连接条件
     *
     * @param clazz     条件字段所在类型
     * @param name      条件字段名称
     * @param condition 条件 SearchCondition里面定义的条件
     * @param value     条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper orWhere(Class<? extends Persistable> clazz, String name, String condition, Object value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, condition, new ConstantExpression(value));
    }

    /**
     * 或连接条件
     *
     * @param name      条件字段名称
     * @param condition 条件 SearchCondition里面定义的条件
     * @param value     条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper orWhere(String name, String condition, Object value) {
        return orWhere(mainClazz, name, condition, value);
    }

    /**
     * IBA值类型和属性定义类型的关系映射
     */
    private static Map<Class<? extends AbstractContextualValue>, Class<? extends AbstractAttributeDefinition>>
            ibaTypeMap = new HashMap<>();

    static {
        ibaTypeMap.put(IntegerValue.class, IntegerDefinition.class);
        ibaTypeMap.put(StringValue.class, StringDefinition.class);
        ibaTypeMap.put(FloatValue.class, FloatDefinition.class);
        ibaTypeMap.put(TimestampValue.class, TimestampDefinition.class);
        ibaTypeMap.put(URLValue.class, URLDefinition.class);
    }

    /**
     * IBA匹配条件
     *
     * @param IBAValueClass IBA值类型
     * @param clazz         软属性所在对象
     * @param name          软属性名称
     * @param condition     匹配条件
     * @param value         匹配值
     */
    private QsHelper whereIBAAny(Class<? extends AbstractContextualValue> IBAValueClass
            , Class<? extends Persistable> clazz, String name, String condition, Object value) {
        Class<? extends AbstractAttributeDefinition> IBADefinitionClass = ibaTypeMap.get(IBAValueClass);
        if (IBADefinitionClass == null) {
            throw new IllegalArgumentException("不支持的查询类型：" + IBAValueClass.getName());
        }
        QsHelper ibaQs = new QsHelper(IBAValueClass, false);
        ibaQs.equal(IBADefinitionClass, "NAME", name);
        ibaQs.andEqual(IBAValueClass, "IDA3A6", IBADefinitionClass, "IDA2A2");
        ibaQs.andEqual("CLASSNAMEKEYA4", clazz.getName());
        ibaQs.andWhere(IBAValueClass, "VALUE", condition, value);
        ibaQs.select("IDA3A4");
        inSubExpr(clazz, "IDA2A2", ibaQs.getQs());
        return this;
    }

    /**
     * IBA值between条件
     *
     * @param IBAHolderType IBA值所在对象
     * @param name          IBA属性名
     * @param minValue      最小值
     * @param maxValue      最大值
     * @return 查询对象
     */
    public QsHelper whereIBABetween(Class<? extends Persistable> IBAHolderType, String name, Timestamp minValue, Timestamp maxValue) {
        return whereIBABetween(IBAHolderType, name, TimestampValue.class, new AttributeRange(minValue, maxValue));
    }

    /**
     * IBA值between条件
     *
     * @param IBAHolderType IBA值所在对象
     * @param name          IBA属性名
     * @param minValue      最小值
     * @param maxValue      最大值
     * @return 查询对象
     */
    public QsHelper whereIBABetween(Class<? extends Persistable> IBAHolderType, String name, long minValue, long maxValue) {
        return whereIBABetween(IBAHolderType, name, TimestampValue.class, new AttributeRange(minValue, maxValue));
    }

    /**
     * IBA值between条件
     *
     * @param IBAHolderType IBA值所在对象
     * @param name          IBA属性名
     * @param minValue      最小值
     * @param maxValue      最大值
     * @return 查询对象
     */
    public QsHelper whereIBABetween(Class<? extends Persistable> IBAHolderType, String name, int minValue, int maxValue) {
        return whereIBABetween(IBAHolderType, name, TimestampValue.class, new AttributeRange(minValue, maxValue));
    }

    /**
     * IBA值between条件
     *
     * @param IBAHolderType IBA值所在对象
     * @param name          IBA属性名
     * @param minValue      最小值
     * @param maxValue      最大值
     * @return 查询对象
     */
    public QsHelper whereIBABetween(Class<? extends Persistable> IBAHolderType, String name, float minValue, float maxValue) {
        return whereIBABetween(IBAHolderType, name, TimestampValue.class, new AttributeRange(minValue, maxValue));
    }

    /**
     * @param IBAHolderType IBA Holder类型
     * @param name          IBA属性名称
     * @param IBAValueType  IBA属性值类型
     * @param valueRange    值范围
     * @return 查询对象
     */
    private QsHelper whereIBABetween(Class<? extends Persistable> IBAHolderType, String name, Class<? extends AbstractContextualValue> IBAValueType, AttributeRange valueRange) {
        Class<? extends AbstractAttributeDefinition> IBADefinitionType = ibaTypeMap.get(TimestampValue.class);
        if (IBADefinitionType == null) {
            throw new IllegalArgumentException("不支持的查询类型：" + IBAValueType.getName());
        }
        QsHelper ibaQs = new QsHelper(IBAValueType, false);
        ibaQs.equal(IBADefinitionType, "NAME", name);
        ibaQs.andEqual(IBAValueType, "IDA3A6", IBADefinitionType, "IDA2A2");
        ibaQs.andEqual("CLASSNAMEKEYA4", IBAHolderType.getName());
        ibaQs.andBetween(IBAValueType, "VALUE", valueRange);
        ibaQs.select("IDA3A4");
        inSubExpr(IBAHolderType, "IDA2A2", ibaQs.getQs());
        return this;
    }

    /**
     * IBA匹配条件
     *
     * @param clazz     软属性所在对象
     * @param name      软属性名称
     * @param condition 匹配条件
     * @param value     匹配值
     */
    private QsHelper whereIBA(Class<? extends Persistable> clazz, String name, String condition, Long value) {
        return whereIBAAny(IntegerValue.class, clazz, name, condition, value);
    }

    /**
     * IBA匹配条件
     *
     * @param clazz     软属性所在对象
     * @param name      软属性名称
     * @param condition 匹配条件
     * @param value     匹配值
     */
    private QsHelper whereIBA(Class<? extends Persistable> clazz, String name, String condition, Timestamp value) {
        return whereIBAAny(TimestampValue.class, clazz, name, condition, value);
    }

    /**
     * IBA匹配条件
     *
     * @param clazz     软属性所在对象
     * @param name      软属性名称
     * @param condition 匹配条件
     * @param value     匹配值
     */
    private QsHelper whereIBA(Class<? extends Persistable> clazz, String name, String condition, Float value) {
        return whereIBAAny(FloatValue.class, clazz, name, condition, value);
    }

    /**
     * IBA匹配条件
     *
     * @param clazz     软属性所在对象
     * @param name      软属性名称
     * @param condition 匹配条件
     * @param value     匹配值
     * @return 返回当前查询帮助类
     */
    public QsHelper whereIBA(Class<? extends Persistable> clazz, String name, String condition, String value) {
        return whereIBAAny(StringValue.class, clazz, name, condition, value);
    }

    /**
     * 与连接IBA属性子查询
     *
     * @param name      iba属性名
     * @param condition 属性值匹配条件
     * @param value     iba属性值
     * @return 返回当前查询帮助类
     */
    public QsHelper whereIBA(String name, String condition, String value) {
        return whereIBAAny(StringValue.class, mainClazz, name, condition, value);
    }

    /**
     * 与连接IBA属性子查询
     *
     * @param clazz     匹配属性所在类
     * @param name      iba属性名
     * @param condition 属性值匹配条件
     * @param value     iba属性值
     * @return 返回当前查询帮助类
     */
    public QsHelper andWhereIBA(Class<? extends Persistable> clazz, String name, String condition, String value) {
        qs.appendAnd();
        return whereIBAAny(StringValue.class, clazz, name, condition, value);
    }

    /**
     * 与连接IBA属性子查询
     *
     * @param name      iba属性名
     * @param condition 属性值匹配条件
     * @param value     iba属性值
     * @return 返回当前查询帮助类
     */
    public QsHelper andWhereIBA(String name, String condition, String value) {
        return andWhereIBA(mainClazz, name, condition, value);
    }

    /**
     * 或连接IBA属性子查询
     *
     * @param clazz     匹配属性所在类
     * @param name      iba属性名
     * @param condition 属性值匹配条件
     * @param value     iba属性值
     * @return 返回当前查询帮助类
     */
    public QsHelper orWhereIBA(Class<? extends Persistable> clazz, String name, String condition, String value) {
        qs.appendOr();
        return whereIBAAny(StringValue.class, clazz, name, condition, value);
    }

    /**
     * 或连接IBA属性子查询
     *
     * @param name      iba属性名
     * @param condition 属性值匹配条件
     * @param value     iba属性值
     * @return 返回当前查询帮助类
     */
    public QsHelper orWhereIBA(String name, String condition, String value) {
        return orWhereIBA(mainClazz, name, condition, value);
    }

    /**
     * IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper in(Class<? extends Persistable> clazz, String name, String[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.IN, new ArrayExpression(values));
    }

    /**
     * IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper in(String name, String[] values) {
        return in(mainClazz, name, values);
    }

    /**
     * IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper in(Class<? extends Persistable> clazz, String name, long[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.IN, new ArrayExpression(values));
    }

    /**
     * IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper in(String name, long[] values) {
        return in(mainClazz, name, values);
    }

    /**
     * IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper andIn(Class<? extends Persistable> clazz, String name, String[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.IN, new ArrayExpression(values));
    }

    /**
     * IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper andIn(String name, String[] values) {
        return andIn(mainClazz, name, values);
    }

    /**
     * IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper andIn(Class<? extends Persistable> clazz, String name, long[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.IN, new ArrayExpression(values));
    }

    /**
     * IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper andIn(String name, long[] values) {
        return andIn(mainClazz, name, values);
    }

    /**
     * IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper orIn(Class<? extends Persistable> clazz, String name, String[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.IN, new ArrayExpression(values));
    }

    /**
     * IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper orIn(String name, String[] values) {
        return orIn(mainClazz, name, values);
    }

    /**
     * IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper orIn(Class<? extends Persistable> clazz, String name, long[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.IN, new ArrayExpression(values));
    }

    /**
     * IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper orIn(String name, long[] values) {
        return orIn(mainClazz, name, values);
    }

    /**
     * IN子表达式 条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param expr  条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper inSubExpr(Class<? extends Persistable> clazz, String name, StatementSpec expr) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.IN, new SubSelectExpression(expr));
    }

    /**
     * IN子表达式 条件
     *
     * @param name 条件字段
     * @param expr 条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper inSubExpr(String name, StatementSpec expr) {
        return inSubExpr(mainClazz, name, expr);
    }

    /**
     * IN 条件查询
     *
     * @param expr  条件左侧表达式
     * @param expr2 条件右侧(值)表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper inSubExpr(RelationalExpression expr, StatementSpec expr2) {
        return where(expr, SearchCondition.IN, new SubSelectExpression(expr2));
    }

    //

    /**
     * IN子表达式 条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param expr  条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper andInSubExpr(Class<? extends Persistable> clazz, String name, StatementSpec expr) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.IN, new SubSelectExpression(expr));
    }

    /**
     * IN子表达式 条件
     *
     * @param name 条件字段
     * @param expr 条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper andInSubExpr(String name, StatementSpec expr) {
        return andInSubExpr(mainClazz, name, expr);
    }

    /**
     * IN 条件查询
     *
     * @param expr  条件左侧表达式
     * @param expr2 条件右侧(值)表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper andInSubExpr(RelationalExpression expr, StatementSpec expr2) {
        return andWhere(expr, SearchCondition.IN, new SubSelectExpression(expr2));
    }

    /**
     * IN子表达式 条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param expr  条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper orInSubExpr(Class<? extends Persistable> clazz, String name, StatementSpec expr) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.IN, new SubSelectExpression(expr));
    }

    /**
     * IN子表达式 条件
     *
     * @param name 条件字段
     * @param expr 条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper orInSubExpr(String name, StatementSpec expr) {
        return orInSubExpr(mainClazz, name, expr);
    }

    /**
     * IN 条件查询
     *
     * @param expr  条件左侧表达式
     * @param expr2 条件右侧(值)表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper orInSubExpr(RelationalExpression expr, StatementSpec expr2) {
        return orWhere(expr, SearchCondition.IN, new SubSelectExpression(expr2));
    }

    /**
     * NOT IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper notIn(Class<? extends Persistable> clazz, String name, String[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.NOT_IN, new ArrayExpression(values));
    }

    /**
     * NOT IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper notIn(String name, String[] values) {
        return notIn(mainClazz, name, values);
    }

    /**
     * NOT IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper andNotIn(Class<? extends Persistable> clazz, String name, String[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.NOT_IN, new ArrayExpression(values));
    }

    /**
     * NOT IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper andNotIn(String name, String[] values) {
        return andNotIn(mainClazz, name, values);
    }

    /**
     * NOT IN 条件查询
     *
     * @param clazz  条件字段所在类型
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper orNotIn(Class<? extends Persistable> clazz, String name, String[] values) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.NOT_IN, new ArrayExpression(values));
    }

    /**
     * NOT IN 条件查询
     *
     * @param name   字段名称
     * @param values 条件值数组
     * @return 返回当前查询帮助类
     */
    public QsHelper orNotIn(String name, String[] values) {
        return orNotIn(mainClazz, name, values);
    }

    /**
     * NOT IN表达式 查询
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param expr  条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper notInSubExpr(Class<? extends Persistable> clazz, String name, StatementSpec expr) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.NOT_IN, new SubSelectExpression(expr));
    }

    /**
     * NOT IN表达式 查询
     *
     * @param name 条件字段
     * @param expr 条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper notInSubExpr(String name, StatementSpec expr) {
        return notInSubExpr(mainClazz, name, expr);
    }

    /**
     * NOT IN表达式 查询
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param expr  条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper andNotInSubExpr(Class<? extends Persistable> clazz, String name, StatementSpec expr) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.NOT_IN, new SubSelectExpression(expr));
    }

    /**
     * NOT IN表达式 查询
     *
     * @param name 条件字段
     * @param expr 条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper andNotInSubExpr(String name, StatementSpec expr) {
        return andNotInSubExpr(mainClazz, name, expr);
    }

    /**
     * NOT IN表达式 查询
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param expr  条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper orNotInSubExpr(Class<? extends Persistable> clazz, String name, StatementSpec expr) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.NOT_IN, new SubSelectExpression(expr));
    }

    /**
     * NOT IN表达式 查询
     *
     * @param name 条件字段
     * @param expr 条件表达式
     * @return 返回当前查询帮助类
     */
    public QsHelper orNotInSubExpr(String name, StatementSpec expr) {
        return orNotInSubExpr(mainClazz, name, expr);
    }

    /**
     * 增加等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  字段名称
     * @param value 条件值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper equal(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加等于条件
     *
     * @param name  字段名称
     * @param value 条件值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper equal(String name, String value) {
        return equal(mainClazz, name, value);
    }

    /**
     * 增加等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper equal(Class<? extends Persistable> clazz, String name, Object value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加等于条件
     *
     * @param name  字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper equal(String name, Object value) {
        return equal(mainClazz, name, value);
    }

    /**
     * 增加等于条件
     *
     * @param clazzA 左侧条件字段所在类型
     * @param nameA  左侧字段名称
     * @param clazzB 右侧字段所在类型
     * @param nameB  右侧字段名称
     * @return 返回当前查询帮助类
     */
    public QsHelper equal(Class<? extends Persistable> clazzA, String nameA, Class<? extends Persistable> clazzB, String nameB) {
        TableColumn tc1 = createColumn(clazzA, nameA);
        TableColumn tc2 = createColumn(clazzB, nameB);
        return where(tc1, SearchCondition.EQUAL, tc2);
    }

    /**
     * 增加等于条件
     *
     * @param nameA  左侧字段名称
     * @param clazzB 右侧字段所在类型
     * @param nameB  右侧字段名称
     * @return 返回当前查询帮助类
     */
    public QsHelper equal(String nameA, Class<? extends Persistable> clazzB, String nameB) {
        return equal(mainClazz, nameA, clazzB, nameB);
    }

    /**
     * 增加等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  字段名称
     * @param value 条件值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqual(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加等于条件
     *
     * @param name  字段名称
     * @param value 条件值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqual(String name, String value) {
        return andEqual(mainClazz, name, value);
    }

    /**
     * 增加等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqual(Class<? extends Persistable> clazz, String name, Object value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加等于条件
     *
     * @param name  字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqual(String name, Object value) {
        return andEqual(mainClazz, name, value);
    }

    /**
     * 增加等于条件
     *
     * @param clazzA 左侧条件字段所在类型
     * @param nameA  左侧字段名称
     * @param clazzB 右侧字段所在类型
     * @param nameB  右侧字段名称
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqual(Class<? extends Persistable> clazzA, String nameA, Class<? extends Persistable> clazzB, String nameB) {
        TableColumn tc1 = createColumn(clazzA, nameA);
        TableColumn tc2 = createColumn(clazzB, nameB);
        return andWhere(tc1, SearchCondition.EQUAL, tc2);
    }

    /**
     * 增加等于条件
     *
     * @param nameA  左侧字段名称
     * @param clazzB 右侧字段所在类型
     * @param nameB  右侧字段名称
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqual(String nameA, Class<? extends Persistable> clazzB, String nameB) {
        return andEqual(mainClazz, nameA, clazzB, nameB);
    }

    /**
     * 增加等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  字段名称
     * @param value 条件值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqual(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加等于条件
     *
     * @param name  字段名称
     * @param value 条件值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqual(String name, String value) {
        return orEqual(mainClazz, name, value);
    }

    /**
     * 增加等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqual(Class<? extends Persistable> clazz, String name, Object value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加等于条件
     *
     * @param name  字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqual(String name, Object value) {
        return orEqual(mainClazz, name, value);
    }

    /**
     * 增加等于条件
     *
     * @param clazzA 左侧条件字段所在类型
     * @param nameA  左侧字段名称
     * @param clazzB 右侧字段所在类型
     * @param nameB  右侧字段名称
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqual(Class<? extends Persistable> clazzA, String nameA, Class<? extends Persistable> clazzB, String nameB) {
        TableColumn tc1 = createColumn(clazzA, nameA);
        TableColumn tc2 = createColumn(clazzB, nameB);
        return orWhere(tc1, SearchCondition.EQUAL, tc2);
    }

    /**
     * 增加等于条件
     *
     * @param nameA  左侧字段名称
     * @param clazzB 右侧字段所在类型
     * @param nameB  右侧字段名称
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqual(String nameA, Class<? extends Persistable> clazzB, String nameB) {
        return orEqual(mainClazz, nameA, clazzB, nameB);
    }

    /**
     * IBA值的比较
     *
     * @param clazz 条件字段所在类型
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper equalIBA(Class<? extends Persistable> clazz, String name, String value) {
        return whereIBA(clazz, name, SearchCondition.EQUAL, value);
    }

    /**
     * IBA值的比较
     *
     * @param clazz 条件字段所在类型
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper equalIBA(Class<? extends Persistable> clazz, String name, Long value) {
        return whereIBA(clazz, name, SearchCondition.EQUAL, value);
    }

    /**
     * IBA值的比较
     *
     * @param clazz 条件字段所在类型
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper equalIBA(Class<? extends Persistable> clazz, String name, Timestamp value) {
        return whereIBA(clazz, name, SearchCondition.EQUAL, value);
    }

    public QsHelper andEqualIBA(Class<? extends Persistable> clazz, String name, Timestamp value) {
        qs.appendAnd();
        return whereIBA(clazz, name, SearchCondition.EQUAL, value);
    }

    /**
     * IBA值的比较
     *
     * @param clazz 条件字段所在类型
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper equalIBA(Class<? extends Persistable> clazz, String name, Float value) {
        return whereIBA(clazz, name, SearchCondition.EQUAL, value);
    }

    /**
     * IBA值的比较
     *
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper equalIBA(String name, String value) {
        return whereIBAAny(StringValue.class, mainClazz, name, SearchCondition.EQUAL, value);
    }

    /**
     * IBA值的比较
     *
     * @param clazz 条件字段所在类型
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqualIBA(Class<? extends Persistable> clazz, String name, String value) {
        return andWhereIBA(clazz, name, SearchCondition.EQUAL, value);
    }

    /**
     * IBA值的比较
     *
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper andEqualIBA(String name, String value) {
        return andEqualIBA(mainClazz, name, value);
    }

    /**
     * IBA值的比较
     *
     * @param clazz 条件字段所在类型
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqualIBA(Class<? extends Persistable> clazz, String name, String value) {
        return orWhereIBA(clazz, name, SearchCondition.EQUAL, value);
    }

    /**
     * IBA值的比较
     *
     * @param name  IBA字段名称
     * @param value 条件值-对象
     * @return 返回当前查询帮助类
     */
    public QsHelper orEqualIBA(String name, String value) {
        return orEqualIBA(mainClazz, name, value);
    }

    /**
     * 增加不等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段名称
     * @param value 条件字段值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper notEqual(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.NOT_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加不等于条件
     *
     * @param name  条件字段名称
     * @param value 条件字段值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper notEqual(String name, String value) {
        return notEqual(mainClazz, name, value);
    }

    /**
     * 增加不等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段名称
     * @param value 条件字段值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper andNotEqual(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.NOT_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加不等于条件
     *
     * @param name  条件字段名称
     * @param value 条件字段值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper andNotEqual(String name, String value) {
        return andNotEqual(mainClazz, name, value);
    }

    /**
     * 增加不等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段名称
     * @param value 条件字段值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper orNotEqual(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.NOT_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加不等于条件
     *
     * @param name  条件字段名称
     * @param value 条件字段值-字符串
     * @return 返回当前查询帮助类
     */
    public QsHelper orNotEqual(String name, String value) {
        return orNotEqual(mainClazz, name, value);
    }

    /**
     * 是否为null
     *
     * @param clazz 对象类型
     * @param name  属性名
     * @return 返回当前查询帮助类
     */
    public QsHelper isNull(Class<? extends Persistable> clazz, String name) {
        try {
            TableColumn tc = createColumn(clazz, name);
            SearchCondition condition = new SearchCondition(tc, SearchCondition.IS_NULL);
            qs.appendWhere(condition, new int[]{0});
        } catch (QueryException e) {
            throw new WTQueryException(e);
        }
        return this;
    }

    /**
     * 增加isNull条件
     *
     * @param name 条件字段
     * @return 返回当前查询帮助类
     */
    public QsHelper isNull(String name) {
        return isNull(mainClazz, name);
    }

    /**
     * 增加isNull条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @return 返回当前查询帮助类
     */
    public QsHelper andIsNull(Class<? extends Persistable> clazz, String name) {
        qs.appendAnd();
        return isNull(clazz, name);
    }

    /**
     * 增加isNull条件
     *
     * @param name 条件字段
     * @return 返回当前查询帮助类
     */
    public QsHelper andIsNull(String name) {
        return andIsNull(mainClazz, name);
    }

    /**
     * 增加isNull条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @return 返回当前查询帮助类
     */
    public QsHelper orIsNull(Class<? extends Persistable> clazz, String name) {
        qs.appendOr();
        return isNull(clazz, name);
    }

    /**
     * 增加isNull条件
     *
     * @param name 条件字段
     * @return 返回当前查询帮助类
     */
    public QsHelper orIsNull(String name) {
        return orIsNull(mainClazz, name);
    }

    /**
     * 增加范围条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param range 值范围
     * @return 返回当前查询帮助类
     */
    public QsHelper between(Class<? extends Persistable> clazz, String name, AttributeRange range) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.BETWEEN, new RangeExpression(range));
    }

    /**
     * 增加范围条件
     *
     * @param name  条件字段
     * @param range 值范围
     * @return 返回当前查询帮助类
     */
    public QsHelper between(String name, AttributeRange range) {
        return between(mainClazz, name, range);
    }

    /**
     * 增加范围条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param range 值范围
     * @return 返回当前查询帮助类
     */
    public QsHelper andBetween(Class<? extends Persistable> clazz, String name, AttributeRange range) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.BETWEEN, new RangeExpression(range));
    }

    /**
     * 增加范围条件
     *
     * @param name  条件字段
     * @param range 值范围
     * @return 返回当前查询帮助类
     */
    public QsHelper andBetween(String name, AttributeRange range) {
        return andBetween(mainClazz, name, range);
    }

    /**
     * 增加范围条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param range 值范围
     * @return 返回当前查询帮助类
     */
    public QsHelper orBetween(Class<? extends Persistable> clazz, String name, AttributeRange range) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.BETWEEN, new RangeExpression(range));
    }

    /**
     * 增加范围条件
     *
     * @param name  条件字段
     * @param range 值范围
     * @return 返回当前查询帮助类
     */
    public QsHelper orBetween(String name, AttributeRange range) {
        return orBetween(mainClazz, name, range);
    }

    /**
     * 增加日期大于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper greaterThanOrEqual(Class<? extends Persistable> clazz, String name, Date value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.GREATER_THAN_OR_EQUAL, new DateExpression(value));
    }

    /**
     * 增加日期大于等于条件
     *
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper greaterThanOrEqual(String name, Date value) {
        return greaterThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加日期大于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     * @return 返回当前查询帮助类
     */
    public QsHelper andGreaterThanOrEqual(Class<? extends Persistable> clazz, String name, Date value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.GREATER_THAN_OR_EQUAL, new DateExpression(value));
    }

    /**
     * 增加日期大于等于条件
     *
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper andGreaterThanOrEqual(String name, Date value) {
        return andGreaterThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加日期大于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper orGreaterThanOrEqual(Class<? extends Persistable> clazz, String name, Date value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.GREATER_THAN_OR_EQUAL, new DateExpression(value));
    }

    /**
     * 增加日期大于等于条件
     *
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper orGreaterThanOrEqual(String name, Date value) {
        return orGreaterThanOrEqual(mainClazz, name, value);
    }

    /**
     * 大于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper greaterThanOrEqual(Class<? extends Persistable> clazz, String name, long value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.GREATER_THAN_OR_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加大于等于条件
     *
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper greaterThanOrEqual(String name, long value) {
        return greaterThanOrEqual(mainClazz, name, value);
    }

    /**
     * 大于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper andGreaterThanOrEqual(Class<? extends Persistable> clazz, String name, long value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.GREATER_THAN_OR_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加大于等于条件
     *
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper andGreaterThanOrEqual(String name, long value) {
        return andGreaterThanOrEqual(mainClazz, name, value);
    }

    /**
     * 大于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper orGreaterThanOrEqual(Class<? extends Persistable> clazz, String name, long value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.GREATER_THAN_OR_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加大于等于条件
     *
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper orGreaterThanOrEqual(String name, long value) {
        return orGreaterThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加日期小于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper lessThanOrEqual(Class<? extends Persistable> clazz, String name, Date value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.LESS_THAN_OR_EQUAL, new DateExpression(value));
    }

    /**
     * 增加日期小于等于条件
     *
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper lessThanOrEqual(String name, Date value) {
        return lessThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加小于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper lessThanOrEqual(Class<? extends Persistable> clazz, String name, double value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.LESS_THAN_OR_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加小于等于条件
     *
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper lessThanOrEqual(String name, double value) {
        return lessThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加日期小于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper andLessThanOrEqual(Class<? extends Persistable> clazz, String name, Date value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.LESS_THAN_OR_EQUAL, new DateExpression(value));
    }

    /**
     * 增加日期小于等于条件
     *
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper andLessThanOrEqual(String name, Date value) {
        return andLessThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加小于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper andLessThanOrEqual(Class<? extends Persistable> clazz, String name, double value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.LESS_THAN_OR_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加小于等于条件
     *
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper andLessThanOrEqual(String name, double value) {
        return andLessThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加日期小于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper orLessThanOrEqual(Class<? extends Persistable> clazz, String name, Date value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.LESS_THAN_OR_EQUAL, new DateExpression(value));
    }

    /**
     * 增加日期小于等于条件
     *
     * @param name  条件字段
     * @param value 条件值-日期
     * @return 返回当前查询帮助类
     */
    public QsHelper orLessThanOrEqual(String name, Date value) {
        return orLessThanOrEqual(mainClazz, name, value);
    }

    /**
     * 增加小于等于条件
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper orLessThanOrEqual(Class<? extends Persistable> clazz, String name, double value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.LESS_THAN_OR_EQUAL, new ConstantExpression(value));
    }

    /**
     * 增加小于等于条件
     *
     * @param name  条件字段
     * @param value 条件值
     * @return 返回当前查询帮助类
     */
    public QsHelper orLessThanOrEqual(String name, double value) {
        return orLessThanOrEqual(mainClazz, name, value);
    }

    /**
     * LIKE 条件表，会自动将条件值里面的*替换为%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，支持模糊匹配，模糊匹配使用*或者%
     * @return 返回当前查询帮助类
     */
    public QsHelper andLikeDirect(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.LIKE, new ConstantExpression(value.replaceAll("\\*", "%")));
    }

    /**
     * LIKE 条件表，会自动将条件值里面的*替换为%
     *
     * @param name  条件字段
     * @param value 条件值，支持模糊匹配，模糊匹配使用*或者%
     * @return 返回当前查询帮助类
     */
    public QsHelper andLikeDirect(String name, String value) {
        return andLikeDirect(mainClazz, name, value);
    }

    /**
     * 增加 LIKE 条件 ，会在传入的值两侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，模糊匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper like(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.LIKE, new ConstantExpression("%" + value + "%"));
    }

    /**
     * 增加 LIKE 条件 ，会在传入的值两侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，模糊匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper like(String name, String value) {
        return like(mainClazz, name, value);
    }

    /**
     * 增加 LIKE 条件 ，会在传入的值两侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，模糊匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.LIKE, new ConstantExpression("%" + value + "%"));
    }

    /**
     * 增加 LIKE 条件 ，会在传入的值两侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，模糊匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andLike(String name, String value) {
        return andLike(mainClazz, name, value);
    }

    /**
     * 增加 LIKE 条件 ，会在传入的值两侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，模糊匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.LIKE, new ConstantExpression("%" + value + "%"));
    }

    /**
     * 增加 LIKE 条件 ，会在传入的值两侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，模糊匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orLike(String name, String value) {
        return orLike(mainClazz, name, value);
    }

    /**
     * 增加LEFT LIKE条件 ，会在传入的值右侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，左匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper leftLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.LIKE, new ConstantExpression(value + "%"));
    }

    /**
     * 增加LEFT LIKE条件 ，会在传入的值右侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，左匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper leftLike(String name, String value) {
        return leftLike(mainClazz, name, value);
    }

    /**
     * 增加LEFT LIKE条件 ，会在传入的值右侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，左匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andLeftLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.LIKE, new ConstantExpression(value + "%"));
    }

    /**
     * 增加LEFT LIKE条件 ，会在传入的值右侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，左匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andLeftLike(String name, String value) {
        return andLeftLike(mainClazz, name, value);
    }

    /**
     * 增加LEFT LIKE条件 ，会在传入的值右侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，左匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orLeftLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.LIKE, new ConstantExpression(value + "%"));
    }

    /**
     * 增加LEFT LIKE条件 ，会在传入的值右侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，左匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orLeftLike(String name, String value) {
        return orLeftLike(mainClazz, name, value);
    }

    /**
     * RIGHT LIKE条件 ，会在传入的值左侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper rightLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return where(tc1, SearchCondition.LIKE, new ConstantExpression("%" + value));
    }

    /**
     * RIGHT LIKE条件 ，会在传入的值左侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper rightLike(String name, String value) {
        return rightLike(mainClazz, name, value);
    }

    /**
     * RIGHT LIKE条件 ，会在传入的值左侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andRightLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return andWhere(tc1, SearchCondition.LIKE, new ConstantExpression("%" + value));
    }

    /**
     * RIGHT LIKE条件 ，会在传入的值左侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andRightLike(String name, String value) {
        return andRightLike(mainClazz, name, value);
    }

    /**
     * RIGHT LIKE条件 ，会在传入的值左侧增加%
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orRightLike(Class<? extends Persistable> clazz, String name, String value) {
        TableColumn tc1 = createColumn(clazz, name);
        return orWhere(tc1, SearchCondition.LIKE, new ConstantExpression("%" + value));
    }

    /**
     * RIGHT LIKE条件 ，会在传入的值左侧增加%
     *
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orRightLike(String name, String value) {
        return orRightLike(mainClazz, name, value);
    }

    /**
     * 自动根据值是否包含*和% 确定是模糊匹配、做匹配、有匹配还是等于匹配
     *
     * @param isAND 是否“与”连接
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，右匹配
     */
    private QsHelper autoLike(Class<? extends Persistable> clazz, String name, String value) {
        if ((value.startsWith("%") || value.startsWith("*"))
                && (value.endsWith("%") || value.endsWith("*"))) {
            value = value.substring(1, value.length() - 1);
            if (value.length() == 0) {
                throw new WTQueryException("请输入正确的查询条件");
            }
            like(clazz, name, value);
        } else if (value.startsWith("%") || value.startsWith("*")) {
            value = value.substring(1);
            if (value.length() == 0) {
                throw new WTQueryException("请输入正确的查询条件");
            }
            rightLike(clazz, name, value);
        } else if (value.endsWith("%") || value.endsWith("*")) {
            value = value.substring(0, value.length() - 1);
            if (value.length() == 0) {
                throw new WTQueryException("请输入正确的查询条件");
            }
            leftLike(clazz, name, value);
        } else {
            equal(clazz, name, value);
        }
        return this;
    }

    /**
     * 自动根据值是否包含*和% 确定是模糊匹配、做匹配、有匹配还是等于匹配
     *
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper autoLike(String name, String value) {
        return autoLike(mainClazz, name, value);
    }

    /**
     * 自动根据值是否包含*和% 确定是模糊匹配、做匹配、有匹配还是等于匹配
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andAutoLike(Class<? extends Persistable> clazz, String name, String value) {
        qs.appendAnd();
        return autoLike(clazz, name, value);
    }

    /**
     * 自动根据值是否包含*和% 确定是模糊匹配、做匹配、有匹配还是等于匹配
     *
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper andAutoLike(String name, String value) {
        return andAutoLike(mainClazz, name, value);
    }

    /**
     * 自动根据值是否包含*和% 确定是模糊匹配、做匹配、有匹配还是等于匹配
     *
     * @param clazz 条件字段所在类型
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orAutoLike(Class<? extends Persistable> clazz, String name, String value) {
        qs.appendOr();
        return autoLike(clazz, name, value);
    }

    /**
     * 自动根据值是否包含*和% 确定是模糊匹配、做匹配、有匹配还是等于匹配
     *
     * @param name  条件字段
     * @param value 条件值，右匹配
     * @return 返回当前查询帮助类
     */
    public QsHelper orAutoLike(String name, String value) {
        return orAutoLike(mainClazz, name, value);
    }

    /**
     * 设置返回列
     *
     * @param clazz 列所在对象
     * @param name  列对应子弹
     * @return 返回当前查询帮助类
     */
    public QsHelper select(Class<? extends Persistable> clazz, String name) {
        TableColumn column = createColumn(clazz, name);
        try {
            qs.appendSelect(column, false);
        } catch (QueryException e) {
            throw new WTQueryException(e);
        }
        return this;
    }

    /**
     * 设置返回列
     *
     * @param name 列对应子弹
     * @return 返回当前查询帮助类
     */
    public QsHelper select(String name) {
        return select(mainClazz, name);
    }

    /**
     * 排序
     *
     * @param clazz 列所在对象
     * @param name  排序列
     * @return 返回当前查询帮助类
     */
    public QsHelper orderBy(Class<? extends Persistable> clazz, String name) {
        return orderBy(clazz, name, false);
    }

    /**
     * 排序
     *
     * @param name 排序列
     * @return 返回当前查询帮助类
     */
    public QsHelper orderBy(String name) {
        return orderBy(mainClazz, name, false);
    }

    /**
     * 排序
     *
     * @param clazz 列所在对象
     * @param name  排序列
     * @param desc  是否逆序
     * @return 返回当前查询帮助类
     */
    public QsHelper orderBy(Class<? extends Persistable> clazz, String name, boolean desc) {
        TableColumn column = createColumn(clazz, name);
        try {
            OrderBy orderBy = new OrderBy(column, desc);
            int index = qs.getFromClause().getPosition(clazz);
            qs.appendOrderBy(orderBy, new int[]{index});
        } catch (QueryException e) {
            throw new WTQueryException(e);
        }
        return this;
    }

    /**
     * 排序
     *
     * @param name 排序列
     * @param desc 是否逆序
     * @return 返回当前查询帮助类
     */
    public QsHelper orderBy(String name, boolean desc) {
        orderBy(mainClazz, name, desc);
        return this;
    }

    /**
     * 执行查询操作，即执行内部的QuerySpec
     *
     * @return 查询结果
     */
    public QueryResult find() {
        try {
            return PersistenceHelper.manager.find(qs);
        } catch (WTException e) {
            throw new WTQueryException(e);
        }
    }

    /**
     * 返回数据条数
     *
     * @return 数据条数
     */
    public int count() {
        try {
            return PersistenceHelper.manager.find(qs).size();
        } catch (WTException e) {
            throw new WTQueryException(e);
        }
    }

    /**
     * 查找对象集合，适用于简单拿到一个结果集
     *
     * @param clazz 对象类型
     * @param <T>   对象泛型参数
     * @return 对象集合，如果没有查到返回空集合
     */
    public <T extends Persistable> List<T> findList(Class<T> clazz) {
        return findList(clazz, 0);
    }

    final static LatestConfigSpec latestConfigSpec = new LatestConfigSpec();


    /**
     * 查找对象的最新版本集合，适用于简单拿到一个结果集
     *
     * @param clazz 对象类型
     * @param <T>   对象泛型参数
     * @return 对象集合，如果没有查到返回空集合
     */
    public <T extends Persistable> List<T> findLatestList(Class<T> clazz) {
        List<T> list = findList(clazz);
        return filterLatest(list);
    }

    /**
     * 查找对象集合，适用于简单拿到一个结果集
     *
     * @param clazz 对象类型
     * @param index 对象在结果集的位置
     * @param <T>   对象泛型参数
     * @return 对象集合，如果没有查到返回空集合
     */
    public <T extends Persistable> List<T> findList(Class<T> clazz, int index) {
        QueryResult qr = find();
        return findList(qr, clazz, index);
    }

    public <T extends Persistable> List<T> findList(QueryResult qr, Class<T> clazz, int index) {
        List<T> entities = new ArrayList<>();
        while (qr.hasMoreElements()) {
            Object obj = qr.nextElement();
            if (obj == null) {
                continue;
            }
            if (obj instanceof Persistable[]) {
                obj = ((Persistable[]) obj)[index];
            }
            if (obj instanceof Object[]) {
                obj = ((Object[]) obj)[index];
            }
            if (!clazz.isAssignableFrom(obj.getClass())) {
                continue;
            }
            @SuppressWarnings("unchecked")
            T tObj = (T) obj;
            entities.add(tObj);
        }
        return entities;
    }

    /**
     * 查询对象
     *
     * @param clazz 对象类型
     * @param <T>   对象泛型参数
     * @return 对象实例
     */
    public <T extends Persistable> T findObject(Class<T> clazz) {
        QueryResult qr = find();
        while (qr.hasMoreElements()) {
            Object obj = qr.nextElement();
            if (obj == null) {
                continue;
            }
            if (obj instanceof Persistable[]) {
                Persistable[] p = (Persistable[]) obj;
                if (p.length == 0) {
                    continue;
                }
                obj = p[0];
            }
            if (!obj.getClass().equals(clazz)) {
                throw new WTQueryException("类型不匹配");
            }
            @SuppressWarnings("unchecked")
            T tObj = (T) obj;
            return tObj;
        }
        return null;
    }

    @Override
    public String toString() {
        return qs.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        QsHelper qsHelper = (QsHelper) o;
        return Objects.equals(qs, qsHelper.qs);
    }

    @Override
    public int hashCode() {
        return qs.hashCode();
    }

    //一些静态工具方法

    private static QsHelper createQueryBy(Class<? extends Persistable> clazz, String attrName, String... attrValue) {
        if (attrValue.length == 0) {
            throw new IllegalArgumentException("参数个数不能小于1");
        }
        QsHelper qs = new QsHelper(clazz);
        if (attrValue.length == 1) {
            qs.equal(clazz, attrName, attrValue[0]);
        } else {
            qs.in(clazz, attrName, attrValue);
        }
        return qs;
    }

    private static QsHelper createQueryBy(Class<? extends Persistable> clazz, String attrName, long... attrValue) {
        if (attrValue.length == 0) {
            throw new IllegalArgumentException("参数个数不能小于1");
        }
        QsHelper qs = new QsHelper(clazz);
        if (attrValue.length == 1) {
            qs.equal(clazz, attrName, attrValue[0]);
        } else {
            qs.in(clazz, attrName, attrValue);
        }
        return qs;
    }

    /**
     * 查询对象集合
     *
     * @param clazz     对象类型
     * @param attrName  属性名
     * @param attrValue 属性值
     * @param <T>       类型
     * @return 对象集合，如果没有查到返回空集合
     */
    public static <T extends Persistable> List<T> findListBy(Class<T> clazz, String attrName, String... attrValue) {
        QsHelper qs = createQueryBy(clazz, attrName, attrValue);
        return qs.findList(clazz);
    }

    /**
     * 查询对象集合
     *
     * @param clazz     对象类型
     * @param attrName  属性名
     * @param attrValue 属性值
     * @param <T>       类型
     * @return 对象集合，如果没有查到返回空集合
     */
    public static <T extends Persistable> List<T> findListBy(Class<T> clazz, String attrName, long... attrValue) {
        QsHelper qs = createQueryBy(clazz, attrName, attrValue);
        return qs.findList(clazz);
    }

    public static <T extends Persistable> List<T> findLatestListBy(Class<T> clazz, String attrName, long... attrValue) {
        QsHelper qs = createQueryBy(clazz, attrName, attrValue);
        return qs.findLatestList(clazz);
    }

    /**
     * 查询数量
     *
     * @param clazz     对象类型
     * @param attrName  属性名
     * @param attrValue 属性值
     * @return 对象数量
     */
    public static int countBy(Class<? extends Persistable> clazz, String attrName, String... attrValue) {
        QsHelper qs = createQueryBy(clazz, attrName, attrValue);
        return qs.count();
    }

    /**
     * 查询数量
     *
     * @param clazz     对象类型
     * @param attrName  属性名
     * @param attrValue 属性值
     * @return 对象数量
     */
    public static int countBy(Class<? extends Persistable> clazz, String attrName, long... attrValue) {
        QsHelper qs = createQueryBy(clazz, attrName, attrValue);
        return qs.count();
    }

    /**
     * 查询数量
     *
     * @param clazz        对象类型
     * @param ibaAttrName  属性名
     * @param ibaAttrValue 属性值
     * @return 对象数量
     */
    public static int countByIBA(Class<? extends Persistable> clazz, String ibaAttrName, String ibaAttrValue) {
        QsHelper qs = new QsHelper(clazz);
        qs.andEqualIBA(clazz, ibaAttrName, ibaAttrValue);
        return qs.count();
    }

    /**
     * 查询对象
     *
     * @param clazz     对象类型
     * @param attrName  属性名
     * @param attrValue 属性值
     * @param <T>       类型
     * @return 单个对象，如果没有查到则返回null
     */
    public static <T extends Persistable> T findObjectBy(Class<T> clazz, String attrName, String attrValue) {
        QsHelper qs = createQueryBy(clazz, attrName, attrValue);
        return qs.findObject(clazz);
    }

    /**
     * 查询对象
     *
     * @param clazz     对象类型
     * @param attrName  属性名
     * @param attrValue 属性值
     * @param <T>       类型
     * @return 单个对象，如果没有查到则返回null
     */
    public static <T extends Persistable> T findObjectBy(Class<T> clazz, String attrName, long attrValue) {
        QsHelper qs = createQueryBy(clazz, attrName, attrValue);
        return qs.findObject(clazz);
    }

    /**
     * 查询对象集合
     *
     * @param clazz        对象类型
     * @param ibaAttrName  属性名
     * @param ibaAttrValue 属性值
     * @param <T>          类型
     * @return 对象集合，如果没有查到返回空集合
     */
    public static <T extends Persistable> List<T> findListByIBA(Class<T> clazz, String ibaAttrName, String ibaAttrValue) {
        QsHelper qs = new QsHelper(clazz);
        qs.andEqualIBA(clazz, ibaAttrName, ibaAttrValue);
        return qs.findList(clazz);
    }

    /**
     * 根据IBA属性查询对象
     *
     * @param clazz        对象类型
     * @param ibaAttrName  属性名
     * @param ibaAttrValue 属性值
     * @param <T>          类型
     * @return 单个对象，如果没有查到则返回null
     */
    public static <T extends Persistable> T findObjectByIBA(Class<T> clazz, String ibaAttrName, String ibaAttrValue) {
        QsHelper qs = new QsHelper(clazz);
        qs.andEqualIBA(clazz, ibaAttrName, ibaAttrValue);
        return qs.findObject(clazz);
    }

    public static <T extends Persistable> T findObjectByID(Class<T> clazz, long ida2a2) {
        QsHelper qs = createQueryBy(clazz, "IDA2A2", ida2a2);
        return qs.findObject(clazz);
    }

    public static <T extends Persistable> T findObjectByOid(Class<T> clazz, String oid) {
        long ida2a2 = oidToIDA2A2(oid);
        QsHelper qs = createQueryBy(clazz, "IDA2A2", ida2a2);
        return qs.findObject(clazz);
    }

    public static <T extends Persistable> List<T> findListByID(Class<T> clazz, long... ida2a2) {
        QsHelper qs = createQueryBy(clazz, "IDA2A2", ida2a2);
        return qs.findList(clazz);
    }

    /**
     * 根据oid和oid对应的对象类型查询结果
     * 发现个现象：clazz传入的是oid实际对象的父类，也能正确的查询出结果
     *
     * @param clazz 待查询对象类型
     * @param oid   对象oid
     * @param <T>   对象类型
     * @return
     */
    public static <T extends Persistable> List<T> findListByOid(Class<T> clazz, String... oid) {
        long[] ida2a2 = oidArrToIDA2A2(oid);
        QsHelper qs = createQueryBy(clazz, "IDA2A2", ida2a2);
        return qs.findList(clazz);
    }

    /**
     * 根据oid查询结果，必须保证oid都是同一个类型的oid
     *
     * @param oid 对象oid
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T extends Persistable> List<T> findListByOid(String... oid) {
        Class<T> clazz;
        try {
            String oneOid = oid[0];
            int dotIndex = oneOid.indexOf(":");
            String id = oneOid.substring(dotIndex + 1);
            ObjectIdentifier objectIdentifier = new ObjectIdentifier(id);
            clazz = (Class<T>) Class.forName(objectIdentifier.getClassname());
        } catch (WTException | ClassNotFoundException e) {
            throw new WTQueryException(e);
        }
        long[] ida2a2 = oidArrToIDA2A2(oid);
        QsHelper qs = createQueryBy(clazz, "IDA2A2", ida2a2);
        return qs.findList(clazz);
    }

    @SuppressWarnings("unchecked")
    private static <T extends Persistable> List<T> filterLatest(List<T> list) {
        if (list.isEmpty()) {
            return list;
        }
        if (!(list.get(0) instanceof Iterated)) {
            return list;
        }
        QueryResult qr = new QueryResult();
        for (Persistable p : list) {
            ObjectVector v = new ObjectVector();
            v.addElement(p);
            qr.append(v);
        }
        try {
            qr = latestConfigSpec.process(qr);
            list.clear();
            while (qr.hasMoreElements()) {
                list.add((T) qr.nextElement());
            }
        } catch (WTException e) {
            throw new WTQueryException(e);
        }
        return list;
    }

    @SuppressWarnings("unchecked")
    public static <T extends Persistable> List<T> findLatestListByOid(String... oid) {
        List<T> list = findListByOid(oid);
        return filterLatest(list);
    }

    public static <T extends Persistable> T findObjectByOid(String oid) {
        List<T> list = findListByOid(oid);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    public static boolean isBlank(CharSequence cs) {
        int strLen;
        if (cs != null && (strLen = cs.length()) != 0) {
            for (int i = 0; i < strLen; ++i) {
                if (!Character.isWhitespace(cs.charAt(i))) {
                    return false;
                }
            }

            return true;
        } else {
            return true;
        }
    }

    public static long oidToIDA2A2(String oid) {
        return Long.parseLong(StringUtils.split(oid, CommonConstant.COLON)[2]);
    }

    public static long[] oidArrToIDA2A2(String[] oidArr) {
        long[] idArr = new long[oidArr.length];
        for (int i = 0; i < oidArr.length; i++) {
            idArr[i] = oidToIDA2A2(oidArr[i]);
        }
        return idArr;
    }

    public static boolean isNotBlank(CharSequence cs) {
        return !isBlank(cs);
    }

    /**
     * 查询异常类
     * 为什么要单独定义而不是使用Windchill内置的异常？
     * <p>
     * 因为内置异常都是受检异常，必须处理，但是这里基本上没啥处理意义，
     * 最后结果就是每个方法都跟一个throw WTException，还不如使用非受检异常，至少代码简洁一点
     */
    public static class WTQueryException extends RuntimeException {

        public WTQueryException(String message) {
            super(message);
        }

        public WTQueryException(String message, Throwable cause) {
            super(message, cause);
        }

        public WTQueryException(Throwable cause) {
            super(cause);
        }
    }
}
